package com.leenmvc.core.utils.thread;

import com.leenmvc.core.base.BaseEntity;
import com.leenmvc.core.dao.communal.Wrapper;
import com.leenmvc.core.security.entity.core.SysUser;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 统一管理本地线程变量的类
 */
public class ThreadLocalManager {

    private static ThreadLocal<Integer> isLog = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    /**
     * 用户本地线程变量
     */
    private static ThreadLocal<SysUser> sysUser = new ThreadLocal<SysUser>() {
        @Override
        protected SysUser initialValue() {
            return new SysUser();
        }
    };

    /**
     * 实际请求url 本地线程变量
     */
    private static ThreadLocal<String> localURL = new ThreadLocal<String>() {
        @Override
        protected String initialValue() {
            return null;
        }
    };

    /**
     * 在线程行进过程中用到的wrapper列表
     */
    private static ThreadLocal<List<Wrapper>> wrapperList = new ThreadLocal<List<Wrapper>>() {
        @Override
        protected List<Wrapper> initialValue() {
            return new ArrayList<Wrapper>();
        }
    };


    /**
     * 这个map方便同一个线程内部传递变量,并且初始化它的初始值
     */
    private static ThreadLocal<HashMap<String, Object>> globalVariable = new ThreadLocal<HashMap<String, Object>>() {
        @Override
        protected HashMap<String, Object> initialValue() {
            return new HashMap<>();
        }
    };

    /**
     * 本次请求执行时间
     */
    private static ThreadLocal<Long> requestTime = new ThreadLocal<Long>() {
        @Override
        protected Long initialValue() {
            return 0l;
        }
    };

    /**
     * 本地线程变量，存储本次操作结果（是否成功）
     */
    private static ThreadLocal<Integer> statusCode = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    /**
     * 本地线程变量，存储request
     */
    private static ThreadLocal<HttpServletRequest> request = new ThreadLocal<HttpServletRequest>() {
        @Override
        protected HttpServletRequest initialValue() {
            return null;
        }
    };

    public static List<Wrapper> getWrapperList() {
        return wrapperList.get();
    }

    /**
     * 关闭所有的wrapper
     *
     */
    public static void closeAllWrapper() {
        List<Wrapper> wrapperList = getWrapperList();
        for (Wrapper wrapper: wrapperList) {
            BaseEntity.getDialect(wrapper.getCls()).getWrapperFactory().closeWrapper(wrapper, true);
        }
        wrapperList.clear();
    }

    public static void setWrapperList(List<Wrapper> wrapperList) {
        ThreadLocalManager.wrapperList.set(wrapperList);
    }

    public static void addWrapper(Wrapper wrapper) {
        if(null == wrapperList.get()){
            wrapperList.set(new ArrayList<Wrapper>());
        }
        wrapperList.get().add(wrapper);
    }

    public static void removeWrapper(Wrapper wrapper) {
        wrapperList.get().remove(wrapper);
    }

    public static void setUser(SysUser user) {
        ThreadLocalManager.sysUser.set(user);
    }

    public static SysUser getUser() {
        return ThreadLocalManager.sysUser.get();
    }

    public static HttpServletRequest getRequest() {
        return request.get();
    }

    public static Object get(String key) {
        return ThreadLocalManager.globalVariable.get().get(key);
    }

    public static void clearGlobalVariable() {
        ThreadLocalManager.globalVariable.get().clear();
    }

    public static void put(String key, Object value) {
        ThreadLocalManager.globalVariable.get().put(key, value);
    }

    public static void setGlobalVariable(HashMap<String, Object> globalVariable) {
        ThreadLocalManager.globalVariable.set(globalVariable);
    }

    public static void setRequest(HttpServletRequest request) {
        ThreadLocalManager.request.set(request);
    }

    public static void setStatusCode(Integer code) {
        ThreadLocalManager.statusCode.set(code);
    }

    public static Integer getStatusCode() {
        return ThreadLocalManager.statusCode.get();
    }

    public static Long getRequestTime() {
        return requestTime.get();
    }

    public static void setRequestTime(Long requestTime) {
        ThreadLocalManager.requestTime.set(requestTime);
    }

    public static void setIsLog(Integer isLog) {
        ThreadLocalManager.isLog.set(isLog);
    }

    public static int isLog() {
        return ThreadLocalManager.isLog.get();
    }

    public static void setLocalUrl(String url) {
        localURL.set(url);
    }

    public static String getLocalUrl() {
        return localURL.get();
    }


}
